---@class components
---@field mod_pono_grogginess component_mod_pono_grogginess # 困倦/昏迷组件 - 独立实现睡眠机制

---@class component_mod_pono_grogginess
---@field inst ent
---@field knockout_test fun(inst: ent): boolean # 昏迷测试函数
---@field wear_off_duration number # 自动醒来时间(秒)
---@field is_knocked_out boolean # 是否处于昏迷状态
---@field knockout_time number # 昏迷已持续时间
---@field grogginess_removal_task table|nil # 移除grogginess效果的定时任务
local mod_pono_grogginess = Class(

---@param self component_mod_pono_grogginess
---@param inst ent
function(self, inst)
    self.inst = inst
    self.knockout_test = nil
    self.wear_off_duration = 12  -- 默认12秒后自动醒来
    self.is_knocked_out = false
    self.knockout_time = 0
    self.grogginess_removal_task = nil
end,
nil,
{})

---设置昏迷测试函数（返回true时触发昏迷）
---@param fn fun(inst: ent): boolean
function mod_pono_grogginess:SetKnockOutTest(fn)
    self.knockout_test = fn
end

---设置自动醒来的持续时间（秒）
---@param duration number
function mod_pono_grogginess:SetWearOffDuration(duration)
    self.wear_off_duration = duration
end

---检查是否应该昏迷
---@return boolean
function mod_pono_grogginess:CheckKnockOut()
    if self.knockout_test and self.knockout_test(self.inst) then
        self:KnockOut()
        return true
    end
    return false
end

---触发昏迷(自己实现睡眠,不依赖sleeper组件)
function mod_pono_grogginess:KnockOut()
    if self.is_knocked_out then
        return
    end
    
    self.is_knocked_out = true
    self.knockout_time = 0
    
    -- 【核心】强制进入睡眠动画状态
    if self.inst.sg then
        -- 检查当前状态，避免打断帐篷等的睡眠状态
        local current_state = self.inst.sg.currentstate and self.inst.sg.currentstate.name
        if current_state ~= "sleeping" and current_state ~= "bedroll" then
            -- 只有在不是正常睡眠状态时才强制昏迷
            self.inst.sg:GoToState("knockout")
        end
    end
    
    -- 添加 sleeping 标签,让其他系统知道角色在睡觉
    self.inst:AddTag("sleeping")
    
    -- 启动组件更新来处理醒来检测
    self.inst:StartUpdatingComponent(self)
    
    -- 监听受伤事件，被攻击时提前醒来
    if not self.damage_listener then
        self.damage_listener = function(inst, data)
            if self.is_knocked_out then
                self:WakeUp()
            end
        end
        self.inst:ListenForEvent("attacked", self.damage_listener)
    end
end

---组件更新函数（处理醒来时间检测）
function mod_pono_grogginess:OnUpdate(dt)
    if not self.is_knocked_out then
        return
    end
    
    self.knockout_time = self.knockout_time + dt
    
    -- 检查是否到达醒来时间
    if self.knockout_time >= self.wear_off_duration then
        self:WakeUp()
    end
end

---唤醒角色
function mod_pono_grogginess:WakeUp()
    if not self.is_knocked_out then
        return
    end
    
    -- 【关键】立即设置状态和停止更新，防止OnUpdate继续触发
    self.is_knocked_out = false
    self.knockout_time = 0
    self.inst:StopUpdatingComponent(self)
    
    -- 移除睡眠标签
    self.inst:RemoveTag("sleeping")
    
    -- 移除受伤监听
    if self.damage_listener then
        self.inst:RemoveEventCallback("attacked", self.damage_listener)
        self.damage_listener = nil
    end
    
    -- 唤醒角色 - 先播放醒来动画
    if self.inst.sg then
        -- 尝试播放醒来动画
        if self.inst.sg.sg.states.wakeup then
            self.inst.sg:GoToState("wakeup")
        else
            -- 如果没有wakeup状态，直接idle
            self.inst.sg:GoToState("idle")
        end
    end
    
    -- 【关键】醒来时给予少量初始能量，避免立即触发能量为0的惩罚模式
    if self.inst.components.mod_pono_energy then
        local current_energy = self.inst.components.mod_pono_energy:GetVal()
        if current_energy <= 0 then
            -- 给予5点初始能量，足以避免惩罚模式立即触发
            self.inst.components.mod_pono_energy:SetVal(5)
        end
    end
    
    -- 【立即】添加催眠状态（groggy标签 + 移速减慢）持续5秒
    self.inst:AddTag("groggy")
    
    -- 应用催眠减速效果（50%移速）
    if self.inst.components.locomotor then
        local groggy_speed_key = "mod_pono_grogginess_wakeup"
        self.inst.components.locomotor:SetExternalSpeedMultiplier(self.inst, groggy_speed_key, 0.5)
        
        -- 取消之前的grogginess移除任务（如果存在）
        if self.grogginess_removal_task then
            self.grogginess_removal_task:Cancel()
            self.grogginess_removal_task = nil
        end
        
        -- 5秒后移除催眠效果
        self.grogginess_removal_task = self.inst:DoTaskInTime(5, function()
            if self.inst and self.inst.components.locomotor then
                self.inst.components.locomotor:RemoveExternalSpeedMultiplier(self.inst, groggy_speed_key)
                if self.inst:HasTag("groggy") then
                    self.inst:RemoveTag("groggy")
                end
            end
            self.grogginess_removal_task = nil
        end)
    end
end

---检查是否处于昏迷状态
---@return boolean
function mod_pono_grogginess:IsKnockedOut()
    return self.is_knocked_out
end

---清理（移除组件时调用）
function mod_pono_grogginess:OnRemoveFromEntity()
    -- 停止组件更新
    self.inst:StopUpdatingComponent(self)
    
    -- 移除受伤监听
    if self.damage_listener then
        self.inst:RemoveEventCallback("attacked", self.damage_listener)
        self.damage_listener = nil
    end
    
    -- 取消grogginess移除任务
    if self.grogginess_removal_task then
        self.grogginess_removal_task:Cancel()
        self.grogginess_removal_task = nil
    end
    
    if self.is_knocked_out then
        self:WakeUp()
    end
end

return mod_pono_grogginess
